home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / netconf / ipx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-30  |  10.0 KB  |  355 lines

  1. #include <linux/ipx.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <sys/ioctl.h>
  5. #include "internal.h"
  6. #include "netconf.h"
  7. #include "netconf.m"
  8.  
  9. NETCONF_HELP_FILE help_ipx("ipx");
  10. static CONFIG_FILE f_ipx_inter (PROC_NET_IPX_INTER,help_ipx
  11.     ,CONFIGF_PROBED|CONFIGF_OPTIONNAL);
  12.  
  13. static char *tbframe[]={
  14.     "802.2","802.3","EtherII","snap"
  15. };
  16. extern char *tb_netdevices[];
  17.  
  18. static const char IPX[]="ipx";
  19. static const char INTERNAL_NETNUM[]="internal_netnum";
  20. static const char INTERNAL_NODENUM[]="internal_nodenum";
  21. static const char PRIMARY_AUTO[]="primary_auto";
  22. static const char FRAME_AUTO[]="frame_auto";
  23. static const char ACTIVE[]="active";
  24.  
  25. /*
  26.     Load the IPX configuration from /etc/conf.linuxconf
  27. */
  28. PUBLIC IPX_INFO::IPX_INFO()
  29. {
  30.     ipx_active = linuxconf_getvalnum (IPX,ACTIVE,0);
  31.     internal_netnum = linuxconf_getvalnum (IPX,INTERNAL_NETNUM,0);
  32.     internal_nodenum = linuxconf_getvalnum (IPX,INTERNAL_NODENUM,0); 
  33.     primary_auto = linuxconf_getvalnum (IPX,PRIMARY_AUTO,1);
  34.     frame_auto   = linuxconf_getvalnum (IPX,FRAME_AUTO,1); 
  35.     for (int i=0; i<NB_ETH; i++){
  36.         IPX_INTER_INFO *itf = &a[i];
  37.         for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  38.             IPX_FRAME_INFO *fra = &itf->frames[f];
  39.             fra->name = tb_netdevices[i];
  40.             fra->netnum = 0;
  41.             fra->primary = 0;
  42.             fra->active = 0;
  43.             char buf[20];
  44.             sprintf (buf,"%s-%s",tb_netdevices[i],tbframe[f]);
  45.             const char *val = linuxconf_getval (IPX,buf);
  46.             if (val != NULL){
  47.                 int active,primary;
  48.                 sscanf (val,"%x %d %d",&fra->netnum,&active,&primary);
  49.                 fra->primary = (char)primary;
  50.                 fra->active = (char)active;
  51.             }
  52.         }
  53.     }
  54. }
  55. /*
  56.     Probe the IPX's "auto_configuration" flags in the kernel.
  57. */
  58. PRIVATE void IPX_INFO::probe_auto()
  59. {
  60.     /* #Specification: netconf / ipx / ioctl SIOCIPXCFGDATA
  61.         linuxconf use the ioctl SIOCIPXCFGDATA to extract the
  62.         status of the auto configuration flags of the IPX network.
  63.     */
  64.     ipx_config_data    data;
  65.     int s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
  66.     if (s < 0) {
  67.         xconf_error (MSG_U(E_IPXSOCKET
  68.             ,"Can't open IPX control socket\n"
  69.              "Looks ODD to me.\n"
  70.              "Maybe linuxconf is incompatible with the kernel release"));
  71.     }else if (ioctl(s, SIOCIPXCFGDATA, &data) == 0){
  72.         primary_auto = data.ipxcfg_auto_select_primary != 0;
  73.         frame_auto = data.ipxcfg_auto_create_interfaces != 0;
  74.     }
  75. }
  76.  
  77. /*
  78.     Load the IPX configuration from the kernel.
  79. */
  80. PUBLIC IPX_INFO::IPX_INFO(CONFIG_FILE &f)
  81. {
  82.     primary_auto = 0;
  83.     frame_auto = 0;
  84.     internal_netnum = 0;
  85.     internal_nodenum = 0;
  86.     ipx_active = 0;
  87.     int i;
  88.     for (i=0; i<NB_ETH; i++){
  89.         IPX_INTER_INFO *itf = &a[i];
  90.         for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  91.             IPX_FRAME_INFO *fra = &itf->frames[f];
  92.             fra->name = tb_netdevices[i];
  93.             fra->netnum = 0;
  94.             fra->primary = 0;
  95.             fra->active = 0;
  96.         }
  97.     }
  98.     FILE *fin = f.fopen ("r");
  99.     if (fin != NULL){
  100.         /* #Specification: netconf / ipx / file /proc/net/ipx_interface
  101.             Linuxconf interprets the file /proc/net/ipx_interface
  102.             to extract the running configuration in the kernel.
  103.             The first line of this file is a header. The other lines
  104.             have the following format.
  105.  
  106.             #
  107.             network    node    primary    dev    frame
  108.             #
  109.         */
  110.         probe_auto();
  111.         char buf[300];
  112.         int format_err = 1;
  113.         // Skip the header
  114.         if (fgets(buf,sizeof(buf)-1,fin)!=NULL){
  115.             format_err = 0;
  116.             while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
  117.                 char network[100], node[100],primary[100],dev[100],frame[100];
  118.                 if (sscanf (buf,"%s %s %s %s %s"
  119.                     ,network,node,primary,dev,frame)!=5){
  120.                     format_err = 1;
  121.                     break;
  122.                 }else if (stricmp(dev,"Internal")==0){
  123.                     sscanf (network,"%x",&internal_netnum);
  124.                     sscanf (node,"%x",&internal_nodenum);
  125.                 }else{
  126.                     for (i=0; i<NB_ETH; i++){
  127.                         if (stricmp(dev,tb_netdevices[i])==0){
  128.                             IPX_INTER_INFO *itf = &a[i];
  129.                             int f;
  130.                             for (f=0; f<NB_IPX_FRAME_TYPE; f++){
  131.                                 if (stricmp(frame,tbframe[f])==0){
  132.                                     IPX_FRAME_INFO *fra = &itf->frames[f];
  133.                                     fra->active = 1;
  134.                                     fra->primary = stricmp(primary,"Yes")==0;
  135.                                     sscanf (network,"%x",&fra->netnum);
  136.                                     break;
  137.                                 }
  138.                             }
  139.                             if (f==NB_IPX_FRAME_TYPE) format_err = 1;
  140.                             break;
  141.                         }
  142.                     }
  143.                     if (i==NB_ETH) format_err = 1;
  144.                 }
  145.             }
  146.         }
  147.         fclose (fin);
  148.         if (format_err){
  149.             xconf_error (MSG_U(E_IPXFORMAT
  150.                 ,"Invalid format of file %s\n"
  151.                  "Can't manage IPX properly\n")
  152.                 ,f_ipx_inter.getpath());
  153.         }
  154.     }
  155. }
  156.  
  157.  
  158. PUBLIC int IPX_INFO::save()
  159. {
  160.     linuxconf_replace (IPX,ACTIVE,ipx_active);
  161.     linuxconf_replace (IPX,INTERNAL_NETNUM,internal_netnum);
  162.     linuxconf_replace (IPX,INTERNAL_NODENUM,internal_nodenum); 
  163.     linuxconf_replace (IPX,PRIMARY_AUTO,primary_auto);
  164.     linuxconf_replace (IPX,FRAME_AUTO,frame_auto); 
  165.     for (int i=0; i<NB_ETH; i++){
  166.         IPX_INTER_INFO *itf = &a[i];
  167.         for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  168.             IPX_FRAME_INFO *fra = &itf->frames[f];
  169.             char buf[20];
  170.             sprintf (buf,"%s-%s",tb_netdevices[i],tbframe[f]);
  171.             char val[100];
  172.             sprintf (val,"%x %d %d",fra->netnum,fra->active,fra->primary);
  173.             linuxconf_replace (IPX,buf,val);
  174.         }
  175.     }
  176.     return linuxconf_save();
  177. }
  178.     
  179.  
  180. PUBLIC int IPX_INFO::edit()
  181. {
  182.     DIALOG dia;
  183.  
  184.     dia.newf_chk (MSG_U(F_IPXENABLE,"Enable"),ipx_active
  185.         ,MSG_U(F_IPXNETWORK,"IPX networking"));
  186.  
  187.  
  188.     char f_primary = primary_auto ? 0 : 100;    // 100 is anything different 0
  189.     dia.newf_radio (MSG_U(F_IPXAUTOCONFIG,"Autoconfigure")
  190.         ,f_primary,0,MSG_U(F_PRIMARY,"primary"));
  191.     dia.newf_chk (MSG_R(F_IPXAUTOCONFIG),frame_auto
  192.         ,MSG_U(F_FRAMETYPES,"interfaces frame types"));
  193.     int i;
  194.     for (i=0; i<NB_ETH; i++){
  195.         IPX_INTER_INFO *itf = &a[i];
  196.         static const char *tbmsg[]={
  197.             MSG_R(T_FIRSTETH),
  198.             MSG_R(T_SECONDETH),
  199.             MSG_R(T_THIRDETH),
  200.             MSG_R(T_FOURTHETH)
  201.         };
  202.         dia.newf_title ("",tbmsg[i]);
  203.         for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  204.             if (f != 0) dia.newf_title ("","-");
  205.             IPX_FRAME_INFO *fra = &itf->frames[f];
  206.             dia.newf_chk (MSG_U(F_FRAMETYPE,"Frame type"),fra->active,tbframe[f]);
  207.             int id = i*NB_IPX_FRAME_TYPE+f+1;
  208.             if (fra->primary) f_primary = id;
  209.             dia.newf_radio ("",f_primary,id,MSG_U(F_ISPRIMARY
  210.                 ,"is the primary interface"));
  211.             dia.newf_num (MSG_U(F_IPXNETNUM,"Network number(0=probe)"),fra->netnum);
  212.         }
  213.     }
  214.     dia.newf_title ("",MSG_U(T_IPXINTERNAL,"Internal network"));
  215.     dia.newf_num (MSG_U(F_IPXINTERNALNETNUM,"Internal network number(opt)")
  216.         ,internal_netnum);
  217.     dia.newf_num (MSG_U(F_IPXINTERNALNODENUM,"Internal node number(opt)")
  218.         ,internal_nodenum);
  219.     int nof = 0;
  220.     int ret = -1;
  221.     while (1){
  222.         MENU_STATUS code = dia.edit (MSG_U(T_IPXCONF,"IPX interface configuration")
  223.             ,MSG_U(I_IPXCONF,"You must associate a frame type with\n"
  224.                 "a network devices and a network number\n"
  225.                 "For one device, it is possible to have several\n"
  226.                 "combination of frame and network number.\n"
  227.                 "Most linux client machine (IPX client) will be happy\n"
  228.                 "by selecting the \"autoconfigure\" choices.")
  229.             ,help_ipx
  230.             ,nof);
  231.         if (code == MENU_CANCEL || code == MENU_ESCAPE){
  232.             dia.restore();
  233.             break;
  234.         }else if (code == MENU_ACCEPT){
  235.             ret = 0;
  236.             //we have to walk the structures to set/unset the primary field
  237.             //of each potential IPX interface
  238.             //Ony one can be primary
  239.             primary_auto = f_primary == 0;
  240.             for (i=0; i<NB_ETH; i++){
  241.                 IPX_INTER_INFO *itf = &a[i];
  242.                 for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  243.                     IPX_FRAME_INFO *fra = &itf->frames[f];
  244.                     int id = i*NB_IPX_FRAME_TYPE+f+1;
  245.                     fra->primary = f_primary == id;
  246.                 }
  247.             }
  248.             break;
  249.         }
  250.     }
  251.     return ret;
  252. }
  253.  
  254.  
  255. void ipx_edit()
  256. {
  257.     IPX_INFO ipx;
  258.     if (ipx.edit()==0) ipx.save();
  259. }
  260.  
  261. /*
  262.     Activate/update conditionnally the IPX interface configuration
  263. */
  264. PUBLIC int IPX_INFO::set()
  265. {
  266.     int ret = 0;
  267.     IPX_INFO cur(f_ipx_inter);
  268.     if (ipx_active){
  269.         if (primary_auto != cur.primary_auto
  270.             || frame_auto != cur.frame_auto){
  271.             char buf[100];
  272.             sprintf (buf,"--auto_interface=%s --auto_primary=%s"
  273.                 ,frame_auto ? "on" : "off"
  274.                 ,primary_auto ? "on" : "off");
  275.             netconf_system_if("ipx_configure",buf);
  276.         }
  277.         for (int i=0; i<NB_ETH; i++){
  278.             const char *devname = tb_netdevices[i];
  279.             int dev_exist = devlist_devexist (devname);
  280.             IPX_INTER_INFO *itf = &a[i];
  281.             IPX_INTER_INFO *cur_itf = &cur.a[i];
  282.             for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
  283.                 IPX_FRAME_INFO *fra = &itf->frames[f];
  284.                 IPX_FRAME_INFO *cur_fra = &cur_itf->frames[f];
  285.                 /* #Specification: netconf / ipx / managing
  286.                     Activating or not IPX interface is tricky. First we
  287.                     probe the current configuration (running) and compare
  288.                     it with the intend configuration. The problem comes
  289.                     from the fact that IPX interface can configure themselves
  290.                     from network trafic (if frame_auto is on).
  291.  
  292.                     The idea here is to find out if the configuration
  293.                     of one interface is different from what is currently
  294.                     running. If so, then we must configure or unconfigure
  295.                     the interface. If we must unconfigure the interface
  296.                     we must check first if frame_auto is on. If so, the
  297.                     interface has been configured by itself, and we
  298.                     are not allowed to remove it.
  299.                 */
  300.                 int do_something = 0;
  301.                 if (fra->active != cur_fra->active){
  302.                     if (fra->active || !frame_auto){
  303.                         do_something = 1;
  304.                     }
  305.                 }else if (fra->active){
  306.                     if (fra->netnum != cur_fra->netnum
  307.                         && fra->netnum != 0){
  308.                         do_something = 1;
  309.                     }
  310.                     if (fra->primary != cur_fra->primary
  311.                         && (fra->primary || !primary_auto)){
  312.                         do_something = 1;
  313.                     }
  314.                 }
  315.                 if (do_something){
  316.                     char buf[100];
  317.                     if (fra->active){
  318.                         int len = sprintf (buf,"add %s %s %s"
  319.                             ,fra->primary ? "-p" : ""
  320.                             ,devname,tbframe[f]);
  321.                         if (fra->netnum != 0){
  322.                             sprintf (buf+len," %x",fra->netnum);
  323.                         }
  324.                         if (!dev_exist){
  325.                             ret |= device_insmod (devname);
  326.                             dev_exist = 1;    // Shut off for next run
  327.                         }
  328.                     }else{
  329.                         sprintf (buf,"del %s %s",devname,tbframe[f]);
  330.                     }
  331.                     ret |= netconf_system_if ("ipx_interface",buf);
  332.                 }
  333.             }
  334.         }
  335.         if (internal_netnum != cur.internal_netnum
  336.             || internal_nodenum != cur.internal_nodenum){
  337.             if (internal_netnum != 0){
  338.                 char buf[100];
  339.                 sprintf (buf,"add %x %x",internal_netnum,internal_nodenum);
  340.                 ret |= netconf_system_if ("ipx_internal_net",buf);
  341.             }else{
  342.                 ret |= netconf_system_if ("ipx_internal_net","del");
  343.             }
  344.         }
  345.     }
  346.     return ret;
  347. }
  348.  
  349. int ipx_set ()
  350. {
  351.     IPX_INFO info;
  352.     return info.set();
  353. }
  354.  
  355.